package com.kgcx.schedule.service;

import com.kgcx.common.client.order.OrderClient;
import com.kgcx.common.client.organization.DriverClient;
import com.kgcx.common.client.organization.pojo.Driver;
import com.kgcx.common.constant.Cons;
import com.kgcx.common.constant.ErrorCode;
import com.kgcx.core.exception.BusinessException;
import com.kgcx.core.utils.HelpUtil;
import com.kgcx.core.utils.JsonUtil;
import com.kgcx.dbutils.core.model.ParameterMap;
import com.kgcx.dbutils.core.model.RowMap;
import com.kgcx.schedule.client.AirportParking;
import com.kgcx.schedule.client.ParkingClient;
import com.kgcx.schedule.client.StationParking;
import com.kgcx.schedule.domain.*;
import com.kgcx.schedule.mapper.*;
import com.kgcx.schedule.rabbitmq.producer.DriverStateProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 司机动态数据维护
 *
 * @author 袁进勇
 */
@Service
public class DriverStateService {
    private final Logger log = LoggerFactory.getLogger(DriverStateService.class);

    @Autowired
    private DriverInfoMapper driverInfoMapper;
    @Autowired
    private DriverStateMapper driverStateMapper;
    @Autowired
    private DriverParkingMapper driverParkingMapper;
    @Autowired
    private ParkingInfoMapper parkingInfoMapper;
    @Autowired
    private ParkingStateMapper parkingStateMapper;
    @Autowired
    private DriverDurationMapper driverDurationMapper;

    @Autowired
    private DriverNotifyService driverNotifyService;
    @Autowired
    private DriverStateProducer driverStateProducer;

    @Autowired
    private DriverClient driverClient;
    @Autowired
    private ParkingClient parkingClient;
    @Autowired
    private OrderClient orderClient;

    public static Boolean SWITCH = false; // TODO 临时开关，等功能切换过来后再删除

    @Value("${kgcx.schedule.driver-state-switch:false}")
    public void setDriverStateSwitch(Boolean driverStateSwitch) {
        SWITCH = driverStateSwitch;
    }

    public List<RowMap> countDriverDuration(ParameterMap params) {
        return driverDurationMapper.countDriverDurationListPage(params);
    }

    public List<DriverDurationDomain> selectDriverDurationListPage(ParameterMap params) {
        return driverDurationMapper.selectEntityListPage(params);
    }

    public List<DriverInfoDomain> getIdleDriverList(ParameterMap params) {
        if (params.containsKey("city_id")) {
            params.put("standby_city_id", params.get("city_id"));
        }
        params.put("service_state", DriverServiceStateEnum.NO_ORDER);

        return driverInfoMapper.selectIdleDriverListPage(params);
    }

    /**
     * @param driverId
     * @return
     */
    public DriverInfoDomain getStateInfo(Long driverId) {
        return driverInfoMapper.selectEntity(driverId);
    }

    /**
     * 司机上线
     *
     * @param driverId
     * @param lng
     * @param lat
     */
    @Transactional(rollbackFor = Exception.class)
    public void online(Long driverId, String lng, String lat) {
        DriverInfoDomain driverInfo = driverInfoMapper.selectEntity(driverId);
        if (driverInfo == null) {
            driverInfo = addDriverInfo(driverId); // 首次上线时，获取司机信息，插表
        } else {
            driverInfo = syncDriverInfo(driverId); // 非首次上线时，同步司机信息
        }

        driverInfo.setStandby_city_id(0L);
        driverInfo.setAirport_id(0L);
        driverInfo.setStation_id(0L);
        driverInfo.setOnline_time(HelpUtil.getNowTime());

        updateDriverInfo(driverInfo, Cons.DRIVER_STATE_ON, lng, lat);

        // 解锁泊车位
        unlockParking(driverId);

        // 通知监管平台
        driverStateProducer.login(driverInfo, lng, lat);
    }

    /**
     * 司机待命
     *
     * @param driverId
     * @param lng
     * @param lat
     * @param airportId
     * @param stationId
     */
    @Transactional(rollbackFor = Exception.class)
    public void standby(Long driverId, String lng, String lat, Long airportId, Long stationId) {
        airportId = airportId == null ? 0L : airportId;
        stationId = stationId == null ? 0L : stationId;

        // 同步车位信息
        if (airportId > 0) {
            syncAirportParkingInfo(airportId);
        } else if (stationId > 0) {
            syncStationParkingInfo(stationId);
        }

        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);
        driverInfo.setStandby_city_id(getStandbyCityId(driverId, airportId, stationId));
        driverInfo.setAirport_id(airportId);
        driverInfo.setStation_id(stationId);

        updateDriverInfo(driverInfo, Cons.DRIVER_STATE_STAY, lng, lat);

        // 如果司机端进程被杀掉，没有答复入栈邀请，这里再重新发送一次邀请
        List<ParkingInfoDomain> parkingInfos = parkingInfoMapper
                .selectEntityListPage(new ParameterMap("driver_id", driverId));
        if (!HelpUtil.isEmpty(parkingInfos)) {
            driverNotifyService.notifyDriverParking(driverId, parkingInfos.get(0));
            return;
        }

        // 创建车位记录
        addDriverParking(driverId, airportId, stationId);

        // 调派车位
        scheduleParking(airportId, stationId);
    }

    /**
     * 司机入栈中
     *
     * @param driverId
     */
    @Transactional(rollbackFor = Exception.class)
    public void accept(Long driverId) {
        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);

        updateDriverInfo(driverInfo, Cons.DRIVER_STATE_PREIN);

        // 处理泊车位
        DriverParkingDomain driverParking = driverParkingMapper.selectEntity(driverId);
        if (driverParking == null) {
            return;
        }

        driverParking.setUpdate_id(0L);
        driverParking.setUpdate_time(HelpUtil.getNowTime());
        driverParking.setParking_state(ParkingStateEnum.ACCEPT);
        driverParking.setAccept_time(driverParking.getUpdate_time());
        driverParkingMapper.updateEntity(driverParking);

        updateParkingInfo(driverParking);
    }

    /**
     * 司机已入栈
     *
     * @param driverId
     */
    @Transactional(rollbackFor = Exception.class)
    public void stacked(Long driverId) {
        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);

        updateDriverInfo(driverInfo, Cons.DRIVER_STATE_IN);

        // 处理泊车位
        DriverParkingDomain driverParking = driverParkingMapper.selectEntity(driverId);
        if (driverParking == null) {
            return;
        }

        driverParking.setUpdate_id(0L);
        driverParking.setUpdate_time(HelpUtil.getNowTime());
        driverParking.setParking_state(ParkingStateEnum.STACKED);
        driverParking.setStacked_time(driverParking.getUpdate_time());
        driverParkingMapper.updateEntity(driverParking);

        updateParkingInfo(driverParking);
    }

    /**
     * 司机取消入栈
     *
     * @param driverId
     */
    @Transactional(rollbackFor = Exception.class)
    public void reject(Long driverId) {
        // 处理泊车位
        DriverParkingDomain driverParking = driverParkingMapper.selectEntity(driverId);
        if (driverParking == null) {
            return;
        }

        if (ParkingStateEnum.ACCEPT.equals(driverParking.getParking_state())
                || ParkingStateEnum.STACKED.equals(driverParking.getParking_state())) {
            // 还原司机状态为待命，同时把状态更新时间也还原
            DriverInfoDomain driverInfo = new DriverInfoDomain();
            driverInfo.setDriver_id(driverId);
            updateDriverInfo(driverInfo, Cons.DRIVER_STATE_STAY, driverParking.getCreate_time());
        }

        driverParking.setUpdate_id(0L);
        driverParking.setUpdate_time(HelpUtil.getNowTime());
        driverParking.setParking_state(ParkingStateEnum.REJECT);
        driverParking.setReject_time(driverParking.getUpdate_time());
        driverParkingMapper.updateEntity(driverParking);

        updateParkingInfo(driverParking);

        // 解锁泊车位
        // driverParkingMapper.deleteEntity(driverParking.getDriver_id());
        unlockParking(driverParking);
    }

    /**
     * 司机下线
     *
     * @param driverId
     * @param lng
     * @param lat
     */
    @Transactional(rollbackFor = Exception.class)
    public void offline(Long driverId, String lng, String lat) {
        DriverInfoDomain driverInfo = driverInfoMapper.selectEntity(driverId);
        if (driverInfo == null) {
            return;
        }

        driverInfo.setStandby_city_id(0L);
        driverInfo.setAirport_id(0L);
        driverInfo.setStation_id(0L);
        driverInfo.setOffline_time(HelpUtil.getNowTime());

        Long duration = (driverInfo.getOffline_time().getTime() - driverInfo.getOnline_time().getTime()) / (60 * 1000);
        Long totalDuration = driverInfo.getTotal_online_duration();
        driverInfo.setTotal_online_duration(totalDuration == null ? duration : (totalDuration + duration));

        updateDriverInfo(driverInfo, Cons.DRIVER_STATE_OFF, lng, lat);

        addDriverDuration(driverInfo, duration);

        // 解锁泊车位
        unlockParking(driverId);

        // 通知监管平台
        driverStateProducer.logout(driverInfo, lng, lat);
    }

    // @Transactional(rollbackFor = Exception.class)
    public void orderScheduled(Long driverId, String orderNo) {
        updateDriverServiceState(driverId, DriverServiceStateEnum.HAS_ORDER, orderNo);
    }

    @Transactional(rollbackFor = Exception.class)
    public void orderStarted(Long driverId) {
        updateDriverServiceState(driverId, DriverServiceStateEnum.START_SERVICE, null);

        // 处理泊车位
        DriverParkingDomain driverParking = driverParkingMapper.selectEntity(driverId);
        if (driverParking == null) {
            return;
        }

        driverParking.setUpdate_id(0L);
        driverParking.setUpdate_time(HelpUtil.getNowTime());
        driverParking.setParking_state(ParkingStateEnum.LEAVE);
        driverParking.setAccept_time(driverParking.getUpdate_time());
        // driverParkingMapper.updateEntity(driverParking);

        updateParkingInfo(driverParking);

        // 解锁泊车位
        driverParkingMapper.deleteEntity(driverParking.getDriver_id());
        unlockParking(driverParking);
    }

    // @Transactional(rollbackFor = Exception.class)
    public void orderFinished(Long driverId) {
        updateDriverServiceState(driverId, DriverServiceStateEnum.ARRIVE_DEST, null);
    }

    // @Transactional(rollbackFor = Exception.class)
    public void orderCancelled(Long driverId) {
        updateDriverServiceState(driverId, DriverServiceStateEnum.NO_ORDER, "");

        // TODO 需要根据司机的位置，判断是否设置司机状态为上线
        try {

        } catch (Exception e) {

        }
    }

    // @Transactional(rollbackFor = Exception.class)
    public void pushBill(Long driverId) {
        unlockDriver(driverId);
    }

    // @Transactional(rollbackFor = Exception.class)
    public void unlockDriver(Long driverId) {
        updateDriverServiceState(driverId, DriverServiceStateEnum.NO_ORDER, "");

        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);

        Integer driverState = Cons.DRIVER_STATE_ON; // 默认切换为上线
        try {
            // 检查司机是否能服务
            Integer data = orderClient.checkDriverServeState(driverId);
            log.info("检查司机是否能服务结果：" + JsonUtil.toString(data));
            if (data != null) {
                driverState = Cons.DRIVER_STATE_OFF; // 不能服务时强制下线
            }
        } catch (Exception e) {
            driverState = Cons.DRIVER_STATE_ON;
            log.error("检查司机是否能服务失败，司机状态切换为上线！", e);
        }
        log.info("司机状态改为：" + driverState);

        updateDriverInfo(driverInfo, driverState);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void updateDriverServiceState(Long driverId, Integer driverState, String orderNo) {
        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);
        driverInfo.setService_state(driverState);
        if (orderNo != null) {
            driverInfo.setOrder_no(orderNo);
        }

        driverInfo.setUpdate_id(0L);
        driverInfo.setUpdate_time(HelpUtil.getNowTime());
        driverInfoMapper.updateEntity(driverInfo);
    }

    private void updateDriverInfo(DriverInfoDomain driverInfo, Integer driverState) {
        updateDriverInfo(driverInfo, driverState, HelpUtil.getNowTime());
    }

    private void updateDriverInfo(DriverInfoDomain driverInfo, Integer driverState, Timestamp stateUpdateTime) {
        updateDriverInfo(driverInfo, driverState, null, null, stateUpdateTime);
    }

    private void updateDriverInfo(DriverInfoDomain driverInfo, Integer driverState, String lng, String lat) {
        updateDriverInfo(driverInfo, driverState, lng, lat, HelpUtil.getNowTime());
    }

    private void updateDriverInfo(DriverInfoDomain driverInfo, Integer driverState, String lng, String lat,
                                  Timestamp stateUpdateTime) {
        driverInfo.setUpdate_id(0L);
        driverInfo.setUpdate_time(HelpUtil.getNowTime());

        driverInfo.setDriver_state(driverState);
        driverInfo.setState_update_time(stateUpdateTime);

        driverInfoMapper.updateEntity(driverInfo);

        addDriverState(driverInfo, lng, lat);

        // 通知司机端状态变更结果
        driverNotifyService.notifyDriverState(driverInfo.getDriver_id(), driverState);
    }

    private void addDriverState(DriverInfoDomain driverInfo) {
        addDriverState(driverInfo, null, null);
    }

    private void addDriverState(DriverInfoDomain driverInfo, String lng, String lat) {
        DriverStateDomain driverState = new DriverStateDomain();
        driverState.setDriver_id(driverInfo.getDriver_id());
        driverState.setDriver_state(driverInfo.getDriver_state());
        driverState.setLat(lat);
        driverState.setLng(lng);
        driverState.setCreate_id(0L);
        driverState.setCreate_time(HelpUtil.getNowTime());
        driverState.setUpdate_id(0L);
        driverState.setUpdate_time(driverState.getCreate_time());
        driverState.setStatus(Cons.COMMON_STATUS_ACTIVE);
        driverStateMapper.insertEntity(driverState);
    }

    private DriverInfoDomain addDriverInfo(Long driverId) {
        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);

        fillDriverInfo(getDriverFromOrg(driverId), driverInfo);

        driverInfo.setCreate_id(0L);
        driverInfo.setCreate_time(HelpUtil.getNowTime());
        driverInfo.setUpdate_id(0L);
        driverInfo.setUpdate_time(driverInfo.getCreate_time());
        driverInfo.setStatus(Cons.COMMON_STATUS_ACTIVE);

        driverInfo.setDriver_state(Cons.DRIVER_STATE_OFF);
        driverInfo.setState_update_time(driverInfo.getCreate_time());
        driverInfo.setStandby_city_id(0L);
        driverInfo.setAirport_id(0L);
        driverInfo.setStation_id(0L);
        driverInfo.setService_state(DriverServiceStateEnum.NO_ORDER);
        driverInfo.setOrder_no("");
        driverInfo.setOnline_time(driverInfo.getCreate_time());
        driverInfo.setOffline_time(driverInfo.getCreate_time());
        driverInfo.setTotal_online_duration(0L);

        driverInfoMapper.insertEntity(driverInfo);

        addDriverState(driverInfo);

        log.info(String.format("创建司机[%d]信息成功。", driverId));
        return driverInfo;
    }

    private DriverInfoDomain syncDriverInfo(Long driverId) {
        DriverInfoDomain driverInfo = new DriverInfoDomain();
        driverInfo.setDriver_id(driverId);

        try {
            fillDriverInfo(getDriverFromOrg(driverInfo.getDriver_id()), driverInfo);
            log.info(String.format("同步司机[%d]信息成功。", driverId));
        } catch (Exception e) {
            log.warn("同步司机信息失败！", e);
        }

        return driverInfo;
    }

    private void fillDriverInfo(Driver driver, DriverInfoDomain driverInfo) {
        driverInfo.setCity_id(driver.getCityId());
        driverInfo.setAuto_id(driver.getAutoId());
        driverInfo.setAuto_no(driver.getAutoNo());
        driverInfo.setAuto_type(driver.getVehiclePurpose());
        driverInfo.setDriver_id(driver.getKid());
        driverInfo.setDriver_name(driver.getName());
        driverInfo.setDriver_phone(driver.getPhone());
        driverInfo.setDriver_license_id(driver.getLicenseId());
    }

    private Driver getDriverFromOrg(Long driverId) {
        try {
            return driverClient.getDriver(driverId, null);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取司机信息失败，其他异常！", e);
            throw new BusinessException(ErrorCode.SCHEDULE_OTHER_EXCEPTION, "获取司机信息失败，其他异常！", e);
        }
    }

    private void addDriverDuration(DriverInfoDomain driverInfo, Long duration) {
        DriverDurationDomain driverDuration = new DriverDurationDomain();
        driverDuration.setCity_id(driverInfo.getCity_id());
        driverDuration.setAuto_id(driverInfo.getAuto_id());
        driverDuration.setDriver_id(driverInfo.getDriver_id());
        driverDuration.setOnline_time(driverInfo.getOnline_time());
        driverDuration.setOffline_time(driverInfo.getOffline_time());
        driverDuration.setDuration(duration);
        driverDurationMapper.insertEntity(driverDuration);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void syncAirportParkingInfo(Long airportId) {
        try {
            List<AirportParking> parkings = parkingClient
                    .getAirportParkingList(new ParameterMap("airportId", airportId));

            parkingInfoMapper.deleteEntities(new ParameterMap("airport_id", airportId));

            if (HelpUtil.isEmpty(parkings)) {
                return;
            }

            List<DriverParkingDomain> driverParkings = driverParkingMapper
                    .selectEntityListPage(new ParameterMap("airport_id", airportId));
            Map<Long, DriverParkingDomain> driverParkingMap = driverParkings.stream()
                    .collect(Collectors.toMap(DriverParkingDomain::getParking_id, driverParking -> driverParking));

            List<ParkingInfoDomain> parkingInfos = parkings.stream().map(parking -> {
                ParkingInfoDomain parkingInfo = new ParkingInfoDomain();
                parkingInfo.setCity_id(parking.getCityId());
                parkingInfo.setParking_type(ParkingTypeEnum.AIRPORT);
                parkingInfo.setParking_id(parking.getKid());
                parkingInfo.setParking_name(parking.getName());
                parkingInfo.setParking_state(ParkingStateEnum.BLANK);
                parkingInfo.setAirport_id(parking.getAirportId());
                parkingInfo.setAirport_name(parking.getAirportName());
                parkingInfo.setAirport_terminal_id(parking.getAirportTerminalId());
                parkingInfo.setAirport_terminal_name(parking.getAirportTerminalName());
                parkingInfo.setDriver_id(0L);

                DriverParkingDomain driverParking = driverParkingMap.get(parking.getKid());
                if (driverParking != null) {
                    parkingInfo.setParking_state(driverParking.getParking_state());
                    parkingInfo.setDriver_id(driverParking.getDriver_id());
                }

                return parkingInfo;
            }).collect(Collectors.toList());

            parkingInfoMapper.insertEntities(parkingInfos);
        } catch (Exception e) {
            log.warn("同步机场车位信息失败！", e);
            return;
        }
    }

    private void syncStationParkingInfo(Long stationId) {
        try {
            List<StationParking> parkings = parkingClient
                    .getStationParkingList(new ParameterMap("stationId", stationId));

            parkingInfoMapper.deleteEntities(new ParameterMap("station_id", stationId));

            if (HelpUtil.isEmpty(parkings)) {
                return;
            }

            List<DriverParkingDomain> driverParkings = driverParkingMapper
                    .selectEntityListPage(new ParameterMap("station_id", stationId));
            Map<Long, DriverParkingDomain> driverParkingMap = driverParkings.stream()
                    .collect(Collectors.toMap(DriverParkingDomain::getParking_id, driverParking -> driverParking));

            List<ParkingInfoDomain> parkingInfos = parkings.stream().map(parking -> {
                ParkingInfoDomain parkingInfo = new ParkingInfoDomain();
                parkingInfo.setCity_id(parking.getCityId());
                parkingInfo.setParking_type(ParkingTypeEnum.STATION);
                parkingInfo.setParking_id(parking.getKid());
                parkingInfo.setParking_name(parking.getName());
                parkingInfo.setParking_state(ParkingStateEnum.BLANK);
                parkingInfo.setStation_id(parking.getStationId());
                parkingInfo.setStation_name(parking.getStationName());
                parkingInfo.setStation_exit_id(parking.getStationExitId());
                parkingInfo.setStation_exit_name(parking.getStationExitName());
                parkingInfo.setDriver_id(0L); // 0表示未安排司机

                DriverParkingDomain driverParking = driverParkingMap.get(parking.getKid());
                if (driverParking != null) {
                    parkingInfo.setParking_state(driverParking.getParking_state());
                    parkingInfo.setDriver_id(driverParking.getDriver_id());
                }

                return parkingInfo;
            }).collect(Collectors.toList());

            parkingInfoMapper.insertEntities(parkingInfos);
        } catch (Exception e) {
            log.warn("同步高铁站车位信息失败！", e);
            return;
        }
    }

    private void addDriverParking(Long driverId, Long airportId, Long stationId) {
        DriverParkingDomain driverParking = new DriverParkingDomain();
        driverParking.setCreate_id(0L);
        driverParking.setCreate_time(HelpUtil.getNowTime());
        driverParking.setUpdate_id(0L);
        driverParking.setUpdate_time(driverParking.getCreate_time());
        driverParking.setStatus(Cons.COMMON_STATUS_ACTIVE);

        driverParking.setDriver_id(driverId);
        if (airportId > 0) {
            driverParking.setParking_type(ParkingTypeEnum.AIRPORT);
        } else if (stationId > 0) {
            driverParking.setParking_type(ParkingTypeEnum.STATION);
        }
        driverParking.setParking_state(ParkingStateEnum.BLANK);

        driverParkingMapper.deleteEntity(driverId);
        driverParkingMapper.insertEntity(driverParking);
    }

    private void unlockParking(Long driverId) {
        DriverParkingDomain driverParking = driverParkingMapper.selectEntity(driverId);
        if (driverParking == null) {
            return;
        }

        driverParkingMapper.deleteEntity(driverParking.getDriver_id());
        unlockParking(driverParking);
    }

    private void unlockParking(DriverParkingDomain driverParking) {
        driverParking.setParking_state(ParkingStateEnum.BLANK);
        driverParking.setDriver_id(0L);
        updateParkingInfo(driverParking);

        // 重新调派车位
        scheduleParking(driverParking.getAirport_id(), driverParking.getStation_id());
    }

    private void scheduleParking(Long airportId, Long stationId) {
        // 获取空闲车位
        ParameterMap params = new ParameterMap("parking_state", ParkingStateEnum.BLANK);
        addAirportIdOrStationId(params, airportId, stationId);
        List<ParkingInfoDomain> parkingInfos = parkingInfoMapper.selectEntityListPage(params);
        if (HelpUtil.isEmpty(parkingInfos)) {
            if (airportId > 0) {
                log.info(String.format("机场[%d]无空闲车位！", airportId));
            } else if (stationId > 0) {
                log.info(String.format("高铁站[%d]无空闲车位！", stationId));
            }
            return;
        }

        // 获取待邀请的司机列表
        params.setOrderBy("create_time"); // 按待命时间顺序来
        List<DriverParkingDomain> driverParkings = driverParkingMapper.selectEntityListPage(params);

        for (ParkingInfoDomain parkingInfo : parkingInfos) {
            if (HelpUtil.isEmpty(driverParkings)) {
                log.info("待发送入栈邀请的司机列表为空！");
                return;
            }

            DriverParkingDomain driverParking = driverParkings.get(0);
            driverParking.setUpdate_id(0L);
            driverParking.setUpdate_time(HelpUtil.getNowTime());
            driverParking.setParking_type(parkingInfo.getParking_type());
            driverParking.setParking_state(ParkingStateEnum.INVITE);
            driverParking.setParking_id(parkingInfo.getParking_id());
            driverParking.setInvite_time(driverParking.getUpdate_time());
            driverParkingMapper.updateEntity(driverParking);

            updateParkingInfo(driverParking);

            driverNotifyService.notifyDriverParking(driverParking.getDriver_id(), parkingInfo);

            driverParkings.remove(0);
        }
    }

    private void updateParkingInfo(DriverParkingDomain driverParking) {
        ParkingInfoDomain parkingInfo = new ParkingInfoDomain();
        parkingInfo.setParking_type(driverParking.getParking_type());
        parkingInfo.setParking_id(driverParking.getParking_id());
        parkingInfo.setParking_state(driverParking.getParking_state());
        parkingInfo.setDriver_id(driverParking.getDriver_id());
        parkingInfoMapper.updateEntity(parkingInfo);

        addParkingState(parkingInfo);
    }

    private void addParkingState(ParkingInfoDomain parkingInfo) {
        ParkingStateDomain parkingState = new ParkingStateDomain();
        parkingState.setParking_type(parkingInfo.getParking_type());
        parkingState.setParking_id(parkingInfo.getParking_id());
        parkingState.setParking_state(parkingInfo.getParking_state());
        parkingState.setDriver_id(parkingInfo.getDriver_id());
        parkingState.setCreate_id(0L);
        parkingState.setCreate_time(HelpUtil.getNowTime());
        parkingState.setUpdate_id(0L);
        parkingState.setUpdate_time(parkingState.getCreate_time());
        parkingState.setStatus(Cons.COMMON_STATUS_ACTIVE);
        parkingStateMapper.insertEntity(parkingState);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private Long getStandbyCityId(Long driverId, Long airportId, Long stationId) {
        ParameterMap params = new ParameterMap().setPageSize(1);
        addAirportIdOrStationId(params, airportId, stationId);
        List<ParkingInfoDomain> parkingInfos = parkingInfoMapper.selectEntityListPage(params);
        if (!HelpUtil.isEmpty(parkingInfos)) {
            return parkingInfos.get(0).getCity_id();
        }

        return driverInfoMapper.selectEntity(driverId).getCity_id();
    }

    private void addAirportIdOrStationId(ParameterMap params, Long airportId, Long stationId) {
        params.put("airport_id", airportId);
        params.put("station_id", stationId);
        if (airportId > 0) {
            params.remove("station_id");
        } else if (stationId > 0) {
            params.remove("airport_id");
        }
    }
}
